Add security CI baseline and update-integrity fuzz/adversarial evals#22
Merged
Conversation
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
security.yml: golang/govulncheck-action does its own git fetch and fails with 'unable to access ... 400' on org repos — run the tool via 'go run golang.org/x/vuln/cmd/govulncheck@latest ./...' after checkout + setup-go instead. Replace gitleaks/gitleaks-action (needs a paid GITLEAKS_LICENSE secret for org repos) with the MIT-licensed pinned gitleaks binary. Both match the green rendezvous/common pattern. updater.go: CodeQL go/zipslip flagged extractTarGz as a high-severity Zip Slip (CWE-022). filepath.Base already strips traversal, but add an explicit destDir-containment check so the invariant is auditable and CodeQL's dataflow recognises the sanitizer; reject escaping entries.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens CI security and adds adversarial/fuzz EVAL coverage for the updater's core security purpose: SHA256 checksum verification + SLSA attestation gating, fail-closed when
ghis absent.Net-new on top of the existing
ci(test+coverage) andcascadeworkflows. No production behavior change beyond a defense-in-depth extraction cap and a toolchain bump; the fail-closed attestation contract already landed in #21 and is exercised by the evals here.CI jobs added
security.ymlrace—go vet+go test -race ./...(security-scoped race gate, independent of coverage upload).gosec— Go SAST (securego/gosec@v2.27.1).govulncheck— known-vuln call-graph scan (golang/govulncheck-action@v1.0.4).gitleaks— secret scan over history/PR range (gitleaks/gitleaks-action@v3.0.0).dependency-review— PR-only, blocks high-severity vulnerable/incompatible deps (actions/dependency-review-action@v3).codeql.ymlsecurity-extendedqueries, push + PR + weekly schedule (github/codeql-action@v4).Dependabot —
.github/dependabot.ymlalready present (gomod weekly + github-actions weekly); requirement satisfied, unchanged.All actions pinned to official released versions.
Scanner findings + resolutions
govulncheck: 2 findings —
GO-2026-5039(net/textproto) andGO-2026-5037(crypto/x509), both Go stdlib, fixed in go1.25.11. Resolved by bumpinggo.modtogo 1.25.11. Re-scan: clean.gosec: G110 (decompression bomb) —
io.Copyof tar entries had no size cap. Fixed in code: per-entryio.LimitReader(tr, maxDownloadBytes+1)with an over-cap error inextractTarGz.gosec: accepted exclusions (documented inline in
security.yml, minimal, never blanket):G104— best-effortos.Remove/Closeon error-cleanup paths.G204— exec ofgh/launchctlwith internally-built args (no user input).G301/G302— install/staging dirs 0755; extracted artifacts are executables (must be 0755).G304— file paths derive fromInstallDir/temp dir, inherent to an updater.G404—math/randused only for thundering-herd jitter, not secrets.gosec exits 0 with these exclusions; never red, never blanket-disabled.
Evals added (adversarial / update integrity)
FuzzVerifyChecksum— fuzzes thechecksums.txtline parser with adversarial inputs (malformed lines, embedded NULs, giant fields, duplicate/garbage lines, no trailing newline). Asserts: never panics; only returns nil when a line genuinely parses to the correct SHA256 for the archive name (independent cross-check guards against verification bypass). 21k+ execs, no crashes.TestApplyUpdate_TamperedArchiveRefused— eval (e): validchecksums.txtfor the original artifact, but the served archive bytes are swapped (MITM/CDN compromise). Asserts the update is refused and the on-disk daemon is left untouched.Existing
zz_*_test.goalready cover the rest of the matrix and are confirmed green:TestApplyUpdate_ChecksumMismatchSkipAttestation=false=> fail closed —TestVerifyChecksumsAttestation_GhNotInstalled,TestVerifyChecksumsAttestation_FailsClosedWithoutSkipSkipAttestation=trueskips attestation but SHA256 stays mandatory —TestApplyUpdate_SkipAttestationStillRequiresChecksum,TestVerifyChecksumsAttestation_SkipConfigTestApplyUpdate_PassesWithValidChecksumsEvals use the existing fakeable seams (
verifyChecksumsAttestationFn,LookPathviaPATH,httptest) — no realgh/network in CI.Validation (GOWORK=off, go1.25.11)
go buildok ·go vetok ·gofmt -lclean ·go test -race ./...ok ·FuzzVerifyChecksum15s no crashes ·govulncheckclean ·gosecexit 0.